using System;
using Gadgeteer.Interfaces.Graphics;

namespace Gadgeteer.Interfaces.Fakes
{
    public class FakeCharacterDisplay : ICharacterDisplay
    {
        private char[][] lines;
        private int currentRow;
        private int currentColumn;

        public FakeCharacterDisplay()
            : this(BackLightMode.On, 2, 16)
        {
        }

        public FakeCharacterDisplay(BackLightMode mode, int rows, int cols)
        {
            BackLightMode = mode;
            lines = new char[rows][];
            for (int l = 0; l < lines.Length; l++)
            {
                lines[l] = new char[cols];
            }
            PrintString(new string(' ', rows * cols));
        }

        public string GetLine(int index)
        {
            if (index >= lines.Length) throw new ArgumentOutOfRangeException("index", "line is not present.");

            return (new string(lines[index])).TrimEnd();
        }

        public string Line1
        {
            get { return GetLine(0); }
        }

        public string Line2
        {
            get { return GetLine(1); }
        }

        public void Clear()
        {
            for (int l = 0; l < lines.Length; l++)
            {
                for (int i = 0; i < lines[l].Length; i++)
                {
                    lines[l][i] = ' ';
                }
            }
        }

        public void CursorHome()
        {
            currentColumn = 0;
            currentRow = 0;
        }

        public void PrintString(string text)
        {
            for (int i = 0; i < text.Length; i++)
            {
                Putc(text[i]);
            }
        }

        public void Putc(char c)
        {
            lines[currentRow][currentColumn] = c;
            MoveCursor();
        }

        public void Putc(byte c)
        {
            Putc((char)c);
        }

        public bool BackLightIsOn
        {
            get { return BackLightMode == BackLightMode.On; }
        }

        public BackLightMode BackLightMode { get; set; }

        public void SetBacklight(BackLightMode mode)
        {
            BackLightMode = mode;
        }

        public void SetCursor(byte row, byte col)
        {
            if (row >= lines.Length)
                throw new ArgumentOutOfRangeException("row");

            if (col >= lines[row].Length)
                throw new ArgumentOutOfRangeException("col");

            currentRow = row;
            currentColumn = col;
        }

        private void MoveCursor()
        {
            currentColumn++;
            if (currentColumn >= lines[currentRow].Length)
            {
                currentColumn = 0;
                currentRow++;
            }

            if (currentRow >= lines.Length)
                currentRow = 0;
        }


        public byte NumberOfRows
        {
            get { return (byte)lines.Length; }
        }

        public byte NumberOfColumns
        {
            get
            {
                if (lines.Length > 0)
                    return (byte)lines[0].Length;
                return 0;
            }
        }
    }
}
